package com.gagakuai.bpm.camundalistener;


import com.gagakuai.bpm.common.constants.BpmMetaConstants;
import com.gagakuai.bpm.common.enums.BpmCompeleptedTypEnum;
import com.gagakuai.bpm.dao.mapper.ActIdGroupMapper;
import com.gagakuai.bpm.dao.mapper.camunda.ActIdUserMapper;
import com.gagakuai.bpm.dao.mapper.camunda.ActRuTaskMapper;
import com.gagakuai.bpm.dao.mapper.camunda.WorkFlowInstenceMapper;
import com.gagakuai.bpm.domian.dto.camunda.CompletedTypeDto;
import com.gagakuai.bpm.domian.entity.ActIdGroup;
import com.gagakuai.bpm.domian.entity.camuda.ActIdUser;
import com.gagakuai.bpm.domian.entity.camuda.ActRuTask;
import com.gagakuai.bpm.domian.entity.camuda.WorkFlowInstence;
import com.gagakuai.bpm.utils.DateUtils;
import com.gagakuai.bpm.utils.RedisUtil;
import com.gagakuai.bpm.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.camunda.bpm.engine.HistoryService;
import org.camunda.bpm.engine.TaskService;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.DelegateTask;
import org.camunda.bpm.engine.delegate.ExecutionListener;
import org.camunda.bpm.engine.delegate.TaskListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/*
 * @program: bpm_server
 * @description: 会签监听器
 * @author: houhong
 * @create: 2022-05-06 13:51
 */
@Slf4j
public class CountersignListener {

   /* @Autowired
    private ActIdUserMapper actIdUserMapper;

    @Autowired
    private WorkFlowInstenceMapper workFlowInstenceMapper;

    @Autowired
    private ActRuTaskMapper actRuTaskMapper;

    @Autowired
    TaskService taskService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private ActIdGroupMapper actIdGroupMapper;


    private AtomicBoolean hasOwnerTask = new AtomicBoolean(true);


    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private RedisTemplate redisTemplate;


    private Map<String, String> keyCacheMap;

    private Map<String, String> addInstanceCacheMap;

    private static AtomicBoolean SWITCH = new AtomicBoolean(false);
    //启动定时任务
    private ScheduledExecutorService updateParamExecute;

    List<String> groupList = null;

    @PostConstruct
    public void initGroup() {

        List<ActIdGroup> actIdGroups = actIdGroupMapper.selectByAll(null);

        groupList = actIdGroups.stream()
                .map(ActIdGroup::getId).distinct().collect(Collectors.toList());

        keyCacheMap = new ConcurrentHashMap<>();

        addInstanceCacheMap = new ConcurrentHashMap<>();

        if (SWITCH.compareAndSet(false, true)) {
            //启动定时任务
            updateParamExecute = Executors.newScheduledThreadPool(1, new ThreadFactory() {
                @Override
                public Thread newThread(Runnable r) {
                    Thread t = new Thread(r);
                    t.setName("com.hx.bpm.sync.Worker");
                    return t;
                }
            });
            updateParamExecute.scheduleAtFixedRate(() -> {
                log.info("#执行定时从数据库捞最新的人员名单#");
                actIdGroupMapper.selectByAll(null);
                groupList = actIdGroups.stream()
                        .map(ActIdGroup::getId).distinct().collect(Collectors.toList());

            }, 0, 30, TimeUnit.SECONDS);
        }

    }

    @Override
    public void notify(DelegateExecution execution) throws Exception {

        log.info("#进入到执行监听器#");

        List<ActIdUser> userList = actIdUserMapper.selectUserListByRole(groupList);
        Map<String, List<ActIdUser>> map = groupUsers(userList);

        Set<String> keySet = map.keySet();

        for (String groupName : keySet) {
            log.info("#设置角色名:{}#", groupName);
            execution.setVariable(groupName, map.get(groupName).stream().map(ActIdUser::getId).collect(Collectors.toList()));
        }
        //设置dueTime
        execution.setVariable(BpmMetaConstants.DEFAULTASK_DUE_DATE, DateUtils.addDays(new Date(), 1));

        //初始化,设置任务节点的办理方式默认为【一人办毕】；然后将当前的process存入redis中，作为全局可以看到。
        execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, false);


    }


    //定义在任务上
    @Override
    public void notify(DelegateTask delegateExecution) {


        String eventName = delegateExecution.getEventName();
        try {
            listenerLogic(eventName, delegateExecution);
        } catch (Exception e) {

            e.printStackTrace();
        }


    }

    private final synchronized void listenerLogic(String eventName, DelegateTask execution) throws Exception {

        *//*
     *
     *  初始化数据
     *
     *//*

        //// TODO: 2022/7/15 模仿返回上一步的人的做法，设置上一次的taskDefKey
        StringBuffer curKeyBuider = null;
        String processInstanceId = execution.getProcessInstanceId();

        StringBuffer taskOwnerBuild = new StringBuffer();

        taskOwnerBuild.append(BpmMetaConstants.TASK_ORIGIN_OWNER);
        taskOwnerBuild.append(execution.getId());
        log.info("#任务原始拥有者key:{}#", taskOwnerBuild.toString());


        *//*
     *
     *        举列： 其实这里优化的化，是可以设置监听器的
     *       如下流程
     *       A ------> B ------> C ------>D ------F
     *       1：在初始化节点的时候，第一个节点记录下就行了。
     *        // TODO: 2022/7/15 迭代  --> 即设置第一个节点的监听器，然后记录初始状态
     *
     *
     *
     *//*

        //任务创建回调
        if (BpmMetaConstants.TASK_TYPE_CREATE.equals(eventName)) {

            //任务创建后将根据任务Id,将任务原始拥有人存入redis
            //redis在这里保证了原子性
            if (!redisUtil.hasKey(taskOwnerBuild.toString())) {
                redisUtil.set(taskOwnerBuild.toString(), execution.getId() + ":" + execution.getAssignee());
            }


            String lastOwnerStr = null;

            String lastTaskDefKey = null;

            curKeyBuider = new StringBuffer();

            curKeyBuider.append(BpmMetaConstants.BPM_COMPLETED_TYPE_GLOBAL).append(BpmMetaConstants.REDIS_FILE_KEY_SEPTOR)
                    .append(processInstanceId);

            CompletedTypeDto completedTypeDto = null;

            *//*
     *  表明不是第一个节点。
     *
     *//*
            if (redisUtil.hasKey(curKeyBuider.toString())) {

                Map<Object, Object> hmget = redisUtil.hmget(curKeyBuider.toString());
                completedTypeDto = new CompletedTypeDto();
                BeanUtils.populate(completedTypeDto, hmget);

                lastOwnerStr = completedTypeDto.getOriginTaskOwnersStrNotDelegate();


                *//*
     *
     *  维度：流程和节点组成二元组：即是：{processId,taskDefKey}
     *                                      三元组:{processId,taskDefKey,taskId} :
     *                                           表明在同一个节点的不同任务。
     *                    当前的维度以任务为维度，是挂靠在节点下面的。
     *
     *//*

                lastTaskDefKey = completedTypeDto.getTaskDefKey();

                if (execution.getTaskDefinitionKey().equals(completedTypeDto.getTaskDefKey()) &&
                        execution.getProcessInstanceId().equals(completedTypeDto.getProcessId())) {

                    //表明是同一个节点的不同任务，还没有走到下一个节点。不需要更新
                    return;
                }


            }

            *//*
     *
     *  代码走到这里的意义是: (1): 以 流程和节点组成二元组：即是：{processId,taskDefKey}
     *          ：下面的任务已经完成了任务，需要更新节点状态：
     *          比如利用备忘录模式, 记录当前状态，做记录回滚。
     *
     *     举列：
     *       如下流程
     *       A ------> B ------> C ------>D ------F
     *       在初始化节点的时候，第一个节点记录下就行了。
     *
     *     (2):第二个意义是：当前节点已经任务已经完成了，走到了下一个节点了。
     *      比如 A节点已经完成了。 走到了B节点
     *          记录状态 A节点的状态
     *            对于A节点来说，当前的上一个节点的信息都应该是空，
     *            所以对于是否到达第一个节点的判断方法可以是上一个节点是否为空。
     *
     *      (3) 直接调用流程轨迹的数据,然后做去重 就可以知道时间节了
     *
     *     （4)  利用camuda框架提供的解析节点完成。
     *
     *//*
            keyCacheMap.put(processInstanceId, curKeyBuider.toString());

            completedTypeDto = new CompletedTypeDto();

            //到了下一个节点记录上一个节点的taskDefKey --> 备忘录模式
            completedTypeDto.setLastTaskDefKey(lastTaskDefKey);

            completedTypeDto.setProcessId(processInstanceId);
            completedTypeDto.setProcesssDefKey(execution.getProcessDefinitionId());
            completedTypeDto.setTaskId(execution.getId());
            completedTypeDto.setTaskDefKey(execution.getTaskDefinitionKey());

            //到下一个节点，刷新redis -- 记录上一个节点的人
            completedTypeDto.setLastTaskOwnerStr(lastOwnerStr);


            completedTypeDto.setIsAddInstance(BpmMetaConstants.BPM_TASK_NON_ADD_INSTANCE);


            //默认为空
            completedTypeDto.setCurCompleted("");
            //默认是一人办毕;
            completedTypeDto.setCompletedType(BpmCompeleptedTypEnum.ONE_COMPLETED.getCode());
            //设置初始化完成条件
            completedTypeDto.setCompletedCondition("");
            completedTypeDto.setDescription("设置当前实列的当前节点的完成方式");


            // TODO: 2022/3/29 存redis
            Map<Object, Object> completedTypeDtoMap = BeanUtils.describe(completedTypeDto);
            redisUtil.hmset(curKeyBuider.toString(), completedTypeDtoMap);


        } else if (BpmMetaConstants.TASK_TYPE_COMPLETEED.equals(eventName)) {


            String redisKey = keyCacheMap.get(execution.getProcessInstanceId());
            if (StringUtils.isEmpty(redisKey)) {
                //自己拼接
                redisKey = BpmMetaConstants.BPM_COMPLETED_TYPE_GLOBAL
                        + BpmMetaConstants.REDIS_FILE_KEY_SEPTOR + execution.getProcessInstanceId();
            }
            CompletedTypeDto completedTypeDto = null;
            //完成任务
            if (redisUtil.hasKey(redisKey)) {
                Map<Object, Object> hmget = redisUtil.hmget(redisKey);
                completedTypeDto = new CompletedTypeDto();
                BeanUtils.populate(completedTypeDto, hmget);

                if (Objects.isNull(hmget.get(BpmMetaConstants.BPM_CUR_CUR_TASK_OWNER_KEY))) {
                    //从数据库里面查
                    List<String> list = actRuTaskMapper.selectCurTaskOwnerList(processInstanceId);
                    StringBuffer stringBuilder = new StringBuffer();

                    list.stream().forEach(cur -> {
                        stringBuilder.append(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR)
                                .append(cur);
                    });
                    log.info("#原来的任务拥有者{}#", stringBuilder.toString());

                    hmget.put(BpmMetaConstants.BPM_CUR_CUR_TASK_OWNER_KEY, stringBuilder.toString());

                    //将本次任务拥有者发步上去
                    redisUtil.hmset(redisKey, hmget);
                    completedTypeDto.setOriginTaskOwnersStr(stringBuilder.toString());
                } else {
                    //todo ?
                }

              *//*  if(Objects.isNull(hmget.get(BpmMetaConstants.BPM_CUR_CUR_TASK_OWNER_NOT_DELEAGTE_KEY))){

                    //originTaskOwnersStrNotDelegate
                    //从数据库里面查
                    List<String> list = actRuTaskMapper.selectCurTaskOwnerListForDelagate(processInstanceId);
                    StringBuffer stringBuilder = new StringBuffer();

                    list.stream().forEach(cur -> {
                        stringBuilder.append(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR)
                                .append(cur);
                    });
                    log.info("#原来的任务拥有者(非委托){}#", stringBuilder.toString());

                    hmget.put(BpmMetaConstants.BPM_CUR_CUR_TASK_OWNER_NOT_DELEAGTE_KEY, stringBuilder.toString());

                    //将本次任务拥有者发步上去
                    redisUtil.hmset(redisKey, hmget);
                    completedTypeDto.setOriginTaskOwnersStrNotDelegate(stringBuilder.toString());
                }*//*
            }


            if (completedTypeDto.getCompletedType().equals(BpmCompeleptedTypEnum.ONE_COMPLETED.getCode())) {

                //判断当前任务是否加签
                Integer isAddInstance = completedTypeDto.getIsAddInstance();

                //单人办毕未加签
                if (BpmMetaConstants.BPM_TASK_NON_ADD_INSTANCE.equals(isAddInstance) || Objects.isNull(isAddInstance)) {

                    //todo 在这里完成更新上一个defKey?
                    execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, true);

                    //单人办毕加签
                } else if (BpmMetaConstants.BPM_TASK_IS_ADD_INSTANCE.equals(isAddInstance)) {

                    Boolean isCompleted = false;

                    Boolean addInstanceCompleted = false;
                    Boolean originCompleted = false;

                    //从redis里面获取
                    String addInstanceRedisKey = keyCacheMap.get(execution.getProcessInstanceId());

                    if (StringUtils.isEmpty(addInstanceRedisKey)) {
                        addInstanceRedisKey = BpmMetaConstants.BPM_COMPLETED_TYPE_GLOBAL
                                + BpmMetaConstants.REDIS_FILE_KEY_SEPTOR + execution.getProcessInstanceId();
                    }
                    Map<Object, Object> addInstanceMap = redisUtil.hmget(addInstanceRedisKey);
                    CompletedTypeDto addInstanceDto = new CompletedTypeDto();
                    BeanUtils.populate(addInstanceDto, addInstanceMap);

                    //判断任务完成类型
                    String completedType = addInstanceDto.getCompletedType();
                    //任务完成条件
                    String completedCondition = addInstanceDto.getCompletedCondition();
                    //当前人员办情况str
                    String curCompleted = addInstanceDto.getCurCompleted();

                    //加签人
                    String addInstancesStr = addInstanceDto.getAddInstancesStr();
                    //当前加签人办理情况
                    String curAddInstancesCompletedStr = addInstanceDto.getCurAddInstancesCompletedStr();

                    //原来的办理人
                    String originTaskOwnersStr = addInstanceDto.getOriginTaskOwnersStr();

                    //当前原办理人办理情况
                    String curOriginTaskOwnerCompletedStr = addInstanceDto.getCurOriginTaskOwnerCompletedStr();


                    log.info("#当前加签的场景: {},完成条件: {},未修改前的完成条件: {}#", completedType, completedCondition, curCompleted);
                    *//*
     *
     *    新办理规则： 原来办理人的一个人+ 所有的加签人
     *
     *
     *
     *
     *
     *//*
                    //本次回调任务办理人
                    String executionAssignee = execution.getAssignee();

                    //拼接当前办理人buider
                    StringBuffer appendAssigneBuffer = new StringBuffer(curCompleted);

                    //所有的加签办理人
                    List<String> allTaskAssigneList = new CopyOnWriteArrayList<>();
                    //所有的原任务办理人
                    List<String> orignTaskAssigneList = new CopyOnWriteArrayList<>();
                    //当前的加签任务办理人
                    List<String> curAddInstanceAssigneList = new Vector<>();
                    //当前原任务办理人
                    List<String> curOriginAssigneList = new Vector<>();

                    //在这里面
                    if (!addInstancesStr.contains(executionAssignee)) {

                        if (StringUtils.isEmpty(curOriginTaskOwnerCompletedStr)) {

                            curOriginTaskOwnerCompletedStr = new String(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR + executionAssignee);
                        } else {
                            curOriginTaskOwnerCompletedStr = curOriginTaskOwnerCompletedStr + BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR + executionAssignee;
                        }
                    } else {
                        //当前加签任务办理人
                        if (StringUtils.isEmpty(curAddInstancesCompletedStr)) {

                            curAddInstancesCompletedStr = new String(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR + executionAssignee);
                        } else {
                            curAddInstancesCompletedStr = curAddInstancesCompletedStr + BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR + executionAssignee;
                        }
                        List<String> asList = Arrays.asList(curAddInstancesCompletedStr);
                        curAddInstanceAssigneList = new CopyOnWriteArrayList(asList);

                        log.info("#需要办理人:{}#", completedCondition);
                        log.info("#当前办理人:{}#", curCompleted + BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR + executionAssignee);

                    }

                    if (StringUtils.isNonEmpty(curAddInstancesCompletedStr)) {
                        //处理完当前人，-- 进入到判断逻辑
                        List<String> tempAddInstanceList = Arrays.asList(addInstancesStr.split(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR));
                        allTaskAssigneList = new CopyOnWriteArrayList<>(tempAddInstanceList);
                        List<String> asList = Arrays.asList(curAddInstancesCompletedStr.split(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR));
                        curAddInstanceAssigneList = new CopyOnWriteArrayList(asList);

                        //移除""
                        if (Objects.nonNull(curAddInstanceAssigneList)) {
                            curAddInstanceAssigneList.remove("");
                        }
                        if (Objects.nonNull(allTaskAssigneList)) {
                            allTaskAssigneList.remove("");
                        }
                        //两个集合元素是否完全 -- 判断加签人
                        if (checkDiffrent(allTaskAssigneList, curAddInstanceAssigneList)) {
                            addInstanceCompleted = true;
                        }
                    }

                    //判断原任务人 -- 加入委托的场景
                    if (StringUtils.isNonEmpty(curOriginTaskOwnerCompletedStr)) {
                      *//*  //// TODO: 2022/7/7   为了保证再委托的场景下能够完成任务，需要进行从数据库里面捞真实数据
                        List<String> assigneList = actRuTaskMapper.selectCurTaskOwnerListForDelagate(processInstanceId);
                        StringBuilder assigneBuild = new StringBuilder();
                        assigneList.stream().forEach(cur -> {
                            assigneBuild.append(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR)
                                    .append(cur);
                        });*//*

                        //原任务人数
                        List<String> asListOrigin = Arrays.asList(originTaskOwnersStr.split(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR));
                        orignTaskAssigneList = new Vector<>(asListOrigin);
                        //移除加签人
                        final List<String> finalAllTaskAssigneList = allTaskAssigneList;
                        orignTaskAssigneList = orignTaskAssigneList.stream().filter(
                                b -> finalAllTaskAssigneList.stream().noneMatch(id -> Objects.equals(b, id))).collect(Collectors.toList());
                        //当前原原任务人办理情况
                        List<String> asListOriginCur = Arrays.asList(curOriginTaskOwnerCompletedStr.split(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR));
                        curOriginAssigneList = new Vector<>(asListOriginCur);


                        //移除""
                        if (Objects.nonNull(asListOrigin)) {
                            orignTaskAssigneList.remove("");
                        }
                        if (Objects.nonNull(asListOriginCur)) {
                            curOriginAssigneList.remove("");
                        }
                        for (String orign : orignTaskAssigneList) {

                            for (String cur : curOriginAssigneList) {

                                if (cur.equals(orign)) {
                                    originCompleted = true;
                                    break;
                                }
                            }
                        }

                    }

                    if (addInstanceCompleted && originCompleted) {

                        isCompleted = true;
                    }

                    if (isCompleted) {

                        //todo 在这里完成更新上一个defKey?
                        //完成任务
                        execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, true);
                    } else {
                        //更新到redis
                        //当前加签人办理情况
                        addInstanceMap.put(BpmMetaConstants.BPM_CUR_ADDINSTANCE_COMPELTED_TYPE_KEY, curAddInstancesCompletedStr);
                        //当前原办理人完成情况
                        addInstanceMap.put(BpmMetaConstants.BPM_CUR_ORIGIN__KEY, curOriginTaskOwnerCompletedStr);
                        redisUtil.hmset(addInstanceRedisKey, addInstanceMap);
                        execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, false);
                    }
                }

            } else if (completedTypeDto.getCompletedType().equals(BpmCompeleptedTypEnum.ALL_COMPLETED.getCode())) {

                //当前节点任务总数
                Integer nrOfInstances = (Integer) execution.getVariable(BpmMetaConstants.NR_OF_INSTANCES_KEY);
                //已经完成数目
                Integer nrOfCompletedInstances = (Integer) execution.getVariable(BpmMetaConstants.NR_OF_CONPLETED_INSTANCES_KEY);
                nrOfCompletedInstances++;

                if (nrOfCompletedInstances == nrOfInstances) {
                    execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, true);
                } else {
                    execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, false);
                }
            } else {

              *//*  StringBuffer addInstanceAssigneRedisKey = new StringBuffer(BpmMetaConstants.BPM_ADD_INSTANCE_ASSIGNE_KEY);
                addInstanceAssigneRedisKey.append(BpmMetaConstants.REDIS_LINE_KEY_SEPTOR)
                        .append(BpmMetaConstants.REDIS_LINE_KEY_SEPTOR).append(addInstanceDto.getProcessId())
                        .append(BpmMetaConstants.REDIS_LINE_KEY_SEPTOR).append(addInstanceDto.getTaskDefKey())
                        .append(BpmMetaConstants.REDIS_LINE_KEY_SEPTOR).append(addInstanceDto.getTaskId());


                log.info("#新构建的加签人key={}#", addInstanceAssigneRedisKey.toString());

                Map<Object, Object> addInstanceAssigneMap = redisUtil.hmget(addInstanceAssigneRedisKey.toString());

                AddInstanceCacheDto addInstanceCacheDto = new AddInstanceCacheDto();
                BeanUtils.populate(addInstanceCacheDto, addInstanceAssigneMap);


                //构建Key
                StringBuffer judeCompeletedKey = new StringBuffer();

                judeCompeletedKey.append(BpmCompeleptedTypEnum.ONE_COMPLETED.getCode().trim())
                        .append(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR)
                        .append(BpmMetaConstants.ADD_INSTANCE_ASSIGNE)
                        .append(BpmMetaConstants.REDIS_EQQUALS_KEY_SEPTOR)
                        .append(addInstanceCacheDto.getAssigne());

                log.info("#查找的KEY:{}#", addInstanceAssigneRedisKey.toString());
                //按照这个key查找
                if (redisUtil.hasKey(addInstanceAssigneRedisKey.toString())) {

                    //表名只有这个人加签-- 然后完成任务


                    execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, true);
                } else {
                    //更新到redis
                    addInstanceMap.put(BpmMetaConstants.BPM_COMPELTED_TTPE, judeCompeletedKey.toString());
                    redisUtil.hmset(addInstanceAssigneRedisKey.toString(), addInstanceMap);

                    execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, false);


                }
*//*

     *//* StringBuffer getKey = new StringBuffer(addInstanceAssigneRedisKey.toString());
                Set<String> keySet = redisTemplate.keys(getKey.append("*"));

                List<AddInstanceCacheDto> addInstanceCacheDtoList = new ArrayList<>();


                for (String key : keySet) {

                    Map<Object, Object> addInstanceAssigneMap = redisUtil.hmget(key);

                    AddInstanceCacheDto addInstanceCacheDto = new AddInstanceCacheDto();
                    BeanUtils.populate(addInstanceCacheDto, addInstanceAssigneMap);
                    addInstanceCacheDtoList.add(addInstanceCacheDto);

                }
               *//*


            }


        } else if (BpmMetaConstants.TASK_TYPE_DELTED.equals(eventName)) {


            String deleteProcessId = execution.getProcessInstanceId();
            String delteTaskDefKey = execution.getTaskDefinitionKey();
            String ruTaskId = execution.getId();

            curKeyBuider = new StringBuffer();
            curKeyBuider.append(BpmMetaConstants.BPM_COMPLETED_TYPE_GLOBAL).append(BpmMetaConstants.REDIS_FILE_KEY_SEPTOR)
                    .append(processInstanceId);


            *//*
     *  第一次完成任务的时候,判断redis中是否有ownerStr： 如果没有的话，就需要进设置ownler
     *
     *//*
            //从redis里面获取
            Map<Object, Object> addInstanceMap = redisUtil.hmget(curKeyBuider.toString());
            CompletedTypeDto completedTypeDto = new CompletedTypeDto();
            BeanUtils.populate(completedTypeDto, addInstanceMap);
            if (Objects.isNull(completedTypeDto.getOriginTaskOwnersStr())) {

                //从数据库里面查
                List<String> list = actRuTaskMapper.selectCurTaskOwnerList(processInstanceId);
                StringBuffer stringBuilder = new StringBuffer();

                list.stream().forEach(cur -> {
                    stringBuilder.append(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR)
                            .append(cur);
                });
                log.info("#原来的任务拥有者{}#", stringBuilder.toString());

                addInstanceMap.put(BpmMetaConstants.BPM_CUR_CUR_TASK_OWNER_KEY, stringBuilder.toString());

                //将上一次的任务拥有者发步上去
                redisUtil.hmset(curKeyBuider.toString(), addInstanceMap);
            }


            *//*
     *   做数据的清理
     *      1:当前的任务去清除redis中缓存的加签人
     *      2:清除keyCacheMap的信息
     *
     *//*
            StringBuffer deleteInstanceAssigneRedisKey = new StringBuffer(BpmMetaConstants.BPM_ADD_INSTANCE_ASSIGNE_KEY);
            deleteInstanceAssigneRedisKey
                    .append(BpmMetaConstants.REDIS_LINE_KEY_SEPTOR).append(deleteProcessId)
                    .append(BpmMetaConstants.REDIS_LINE_KEY_SEPTOR).append(delteTaskDefKey)
                    .append(BpmMetaConstants.REDIS_LINE_KEY_SEPTOR).append(ruTaskId);

            log.info("#需要删除的key:{}#", deleteInstanceAssigneRedisKey.toString());
            redisUtil.del(deleteInstanceAssigneRedisKey.toString());

            //需要回表查询数据判断当前流程是否结束
            WorkFlowInstence workFlowInstence = workFlowInstenceMapper.selectByPrimaryKey(processInstanceId);

            if (!BpmMetaConstants.PROCESS_ACTIVE.equals(workFlowInstence.getState())) {
                //删除本地缓存。
                keyCacheMap.remove(curKeyBuider.toString());
                // 删除redis缓存
                redisUtil.del(curKeyBuider.toString());
            }

            //任务被删除后删除该任务的拥有者
            redisUtil.del(taskOwnerBuild.toString());
        }
    }


    public static Map<String, List<ActIdUser>> groupUsers(List<ActIdUser> waitList) {


        Map<String, List<ActIdUser>> map = new ConcurrentHashMap<>();

        for (ActIdUser actIdUser : waitList) {

            if (map.containsKey(actIdUser.getGroupName())) {

                List<ActIdUser> actIdUsers = map.get(actIdUser.getGroupName());
                actIdUsers.add(actIdUser);
            } else {
                List<ActIdUser> actIdUsers = new ArrayList<>();
                actIdUsers.add(actIdUser);
                map.put(actIdUser.getGroupName(), actIdUsers);
            }
        }

        return map;
    }

    private static boolean checkDiffrent(List<String> list, List<String> list1) {

        return list.stream().sorted().collect(Collectors.joining())
                .equals(list1.stream().sorted().collect(Collectors.joining()));
    }

/* @Autowired
    private ActIdUserMapper actIdUserMapper;

    @Autowired
    private WorkFlowInstenceMapper workFlowInstenceMapper;

    @Autowired
    private ActRuTaskMapper actRuTaskMapper;

    @Autowired
    TaskService taskService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private ActIdGroupMapper actIdGroupMapper;


    private AtomicBoolean hasOwnerTask = new AtomicBoolean(true);


    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private RedisTemplate redisTemplate;


    private Map<String, String> keyCacheMap;

    private Map<String, String> addInstanceCacheMap;

    private static AtomicBoolean SWITCH = new AtomicBoolean(false);
    //启动定时任务
    private ScheduledExecutorService updateParamExecute;

    List<String> groupList = null;

    @PostConstruct
    public void initGroup() {

        List<ActIdGroup> actIdGroups = actIdGroupMapper.selectByAll(null);

        groupList = actIdGroups.stream()
                .map(ActIdGroup::getId).distinct().collect(Collectors.toList());

        keyCacheMap = new ConcurrentHashMap<>();

        addInstanceCacheMap = new ConcurrentHashMap<>();

        if (SWITCH.compareAndSet(false, true)) {
            //启动定时任务
            updateParamExecute = Executors.newScheduledThreadPool(1, new ThreadFactory() {
                @Override
                public Thread newThread(Runnable r) {
                    Thread t = new Thread(r);
                    t.setName("com.hx.bpm.sync.Worker");
                    return t;
                }
            });
            updateParamExecute.scheduleAtFixedRate(() -> {
                log.info("#执行定时从数据库捞最新的人员名单#");
                actIdGroupMapper.selectByAll(null);
                groupList = actIdGroups.stream()
                        .map(ActIdGroup::getId).distinct().collect(Collectors.toList());

            }, 0, 30, TimeUnit.SECONDS);
        }

    }

    @Override
    public void notify(DelegateExecution execution) throws Exception {

        log.info("#进入到执行监听器#");

        List<ActIdUser> userList = actIdUserMapper.selectUserListByRole(groupList);
        Map<String, List<ActIdUser>> map = groupUsers(userList);

        Set<String> keySet = map.keySet();

        for (String groupName : keySet) {
            log.info("#设置角色名:{}#", groupName);
            execution.setVariable(groupName, map.get(groupName).stream().map(ActIdUser::getId).collect(Collectors.toList()));
        }
        //设置dueTime
        execution.setVariable(BpmMetaConstants.DEFAULTASK_DUE_DATE, DateUtils.addDays(new Date(), 1));

        //初始化,设置任务节点的办理方式默认为【一人办毕】；然后将当前的process存入redis中，作为全局可以看到。
        execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, false);


    }


    //定义在任务上
    @Override
    public void notify(DelegateTask delegateExecution) {


        String eventName = delegateExecution.getEventName();
        try {
            listenerLogic(eventName, delegateExecution);
        } catch (Exception e) {

            e.printStackTrace();
        }


    }

    private final synchronized void listenerLogic(String eventName, DelegateTask execution) throws Exception {

        *//*
     *
     *  初始化数据
     *
     *//*

        //// TODO: 2022/7/15 模仿返回上一步的人的做法，设置上一次的taskDefKey
        StringBuffer curKeyBuider = null;
        String processInstanceId = execution.getProcessInstanceId();

        StringBuffer taskOwnerBuild = new StringBuffer();

        taskOwnerBuild.append(BpmMetaConstants.TASK_ORIGIN_OWNER);
        taskOwnerBuild.append(execution.getId());
        log.info("#任务原始拥有者key:{}#", taskOwnerBuild.toString());


        *//*
     *
     *        举列： 其实这里优化的化，是可以设置监听器的
     *       如下流程
     *       A ------> B ------> C ------>D ------F
     *       1：在初始化节点的时候，第一个节点记录下就行了。
     *        // TODO: 2022/7/15 迭代  --> 即设置第一个节点的监听器，然后记录初始状态
     *
     *
     *
     *//*

        //任务创建回调
        if (BpmMetaConstants.TASK_TYPE_CREATE.equals(eventName)) {

            //任务创建后将根据任务Id,将任务原始拥有人存入redis
            //redis在这里保证了原子性
            if (!redisUtil.hasKey(taskOwnerBuild.toString())) {
                redisUtil.set(taskOwnerBuild.toString(), execution.getId() + ":" + execution.getAssignee());
            }


            String lastOwnerStr = null;

            String lastTaskDefKey = null;

            curKeyBuider = new StringBuffer();

            curKeyBuider.append(BpmMetaConstants.BPM_COMPLETED_TYPE_GLOBAL).append(BpmMetaConstants.REDIS_FILE_KEY_SEPTOR)
                    .append(processInstanceId);

            CompletedTypeDto completedTypeDto = null;

            *//*
     *  表明不是第一个节点。
     *
     *//*
            if (redisUtil.hasKey(curKeyBuider.toString())) {

                Map<Object, Object> hmget = redisUtil.hmget(curKeyBuider.toString());
                completedTypeDto = new CompletedTypeDto();
                BeanUtils.populate(completedTypeDto, hmget);

                lastOwnerStr = completedTypeDto.getOriginTaskOwnersStrNotDelegate();


                *//*
     *
     *  维度：流程和节点组成二元组：即是：{processId,taskDefKey}
     *                                      三元组:{processId,taskDefKey,taskId} :
     *                                           表明在同一个节点的不同任务。
     *                    当前的维度以任务为维度，是挂靠在节点下面的。
     *
     *//*

                lastTaskDefKey = completedTypeDto.getTaskDefKey();

                if (execution.getTaskDefinitionKey().equals(completedTypeDto.getTaskDefKey()) &&
                        execution.getProcessInstanceId().equals(completedTypeDto.getProcessId())) {

                    //表明是同一个节点的不同任务，还没有走到下一个节点。不需要更新
                    return;
                }


            }

            *//*
     *
     *  代码走到这里的意义是: (1): 以 流程和节点组成二元组：即是：{processId,taskDefKey}
     *          ：下面的任务已经完成了任务，需要更新节点状态：
     *          比如利用备忘录模式, 记录当前状态，做记录回滚。
     *
     *     举列：
     *       如下流程
     *       A ------> B ------> C ------>D ------F
     *       在初始化节点的时候，第一个节点记录下就行了。
     *
     *     (2):第二个意义是：当前节点已经任务已经完成了，走到了下一个节点了。
     *      比如 A节点已经完成了。 走到了B节点
     *          记录状态 A节点的状态
     *            对于A节点来说，当前的上一个节点的信息都应该是空，
     *            所以对于是否到达第一个节点的判断方法可以是上一个节点是否为空。
     *
     *      (3) 直接调用流程轨迹的数据,然后做去重 就可以知道时间节了
     *
     *     （4)  利用camuda框架提供的解析节点完成。
     *
     *//*
            keyCacheMap.put(processInstanceId, curKeyBuider.toString());

            completedTypeDto = new CompletedTypeDto();

            //到了下一个节点记录上一个节点的taskDefKey --> 备忘录模式
            completedTypeDto.setLastTaskDefKey(lastTaskDefKey);

            completedTypeDto.setProcessId(processInstanceId);
            completedTypeDto.setProcesssDefKey(execution.getProcessDefinitionId());
            completedTypeDto.setTaskId(execution.getId());
            completedTypeDto.setTaskDefKey(execution.getTaskDefinitionKey());

            //到下一个节点，刷新redis -- 记录上一个节点的人
            completedTypeDto.setLastTaskOwnerStr(lastOwnerStr);


            completedTypeDto.setIsAddInstance(BpmMetaConstants.BPM_TASK_NON_ADD_INSTANCE);


            //默认为空
            completedTypeDto.setCurCompleted("");
            //默认是一人办毕;
            completedTypeDto.setCompletedType(BpmCompeleptedTypEnum.ONE_COMPLETED.getCode());
            //设置初始化完成条件
            completedTypeDto.setCompletedCondition("");
            completedTypeDto.setDescription("设置当前实列的当前节点的完成方式");


            // TODO: 2022/3/29 存redis
            Map<Object, Object> completedTypeDtoMap = BeanUtils.describe(completedTypeDto);
            redisUtil.hmset(curKeyBuider.toString(), completedTypeDtoMap);


        } else if (BpmMetaConstants.TASK_TYPE_COMPLETEED.equals(eventName)) {


            String redisKey = keyCacheMap.get(execution.getProcessInstanceId());
            if (StringUtils.isEmpty(redisKey)) {
                //自己拼接
                redisKey = BpmMetaConstants.BPM_COMPLETED_TYPE_GLOBAL
                        + BpmMetaConstants.REDIS_FILE_KEY_SEPTOR + execution.getProcessInstanceId();
            }
            CompletedTypeDto completedTypeDto = null;
            //完成任务
            if (redisUtil.hasKey(redisKey)) {
                Map<Object, Object> hmget = redisUtil.hmget(redisKey);
                completedTypeDto = new CompletedTypeDto();
                BeanUtils.populate(completedTypeDto, hmget);

                if (Objects.isNull(hmget.get(BpmMetaConstants.BPM_CUR_CUR_TASK_OWNER_KEY))) {
                    //从数据库里面查
                    List<String> list = actRuTaskMapper.selectCurTaskOwnerList(processInstanceId);
                    StringBuffer stringBuilder = new StringBuffer();

                    list.stream().forEach(cur -> {
                        stringBuilder.append(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR)
                                .append(cur);
                    });
                    log.info("#原来的任务拥有者{}#", stringBuilder.toString());

                    hmget.put(BpmMetaConstants.BPM_CUR_CUR_TASK_OWNER_KEY, stringBuilder.toString());

                    //将本次任务拥有者发步上去
                    redisUtil.hmset(redisKey, hmget);
                    completedTypeDto.setOriginTaskOwnersStr(stringBuilder.toString());
                } else {
                    //todo ?
                }

              *//*  if(Objects.isNull(hmget.get(BpmMetaConstants.BPM_CUR_CUR_TASK_OWNER_NOT_DELEAGTE_KEY))){

                    //originTaskOwnersStrNotDelegate
                    //从数据库里面查
                    List<String> list = actRuTaskMapper.selectCurTaskOwnerListForDelagate(processInstanceId);
                    StringBuffer stringBuilder = new StringBuffer();

                    list.stream().forEach(cur -> {
                        stringBuilder.append(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR)
                                .append(cur);
                    });
                    log.info("#原来的任务拥有者(非委托){}#", stringBuilder.toString());

                    hmget.put(BpmMetaConstants.BPM_CUR_CUR_TASK_OWNER_NOT_DELEAGTE_KEY, stringBuilder.toString());

                    //将本次任务拥有者发步上去
                    redisUtil.hmset(redisKey, hmget);
                    completedTypeDto.setOriginTaskOwnersStrNotDelegate(stringBuilder.toString());
                }*//*
            }


            if (completedTypeDto.getCompletedType().equals(BpmCompeleptedTypEnum.ONE_COMPLETED.getCode())) {

                //判断当前任务是否加签
                Integer isAddInstance = completedTypeDto.getIsAddInstance();

                //单人办毕未加签
                if (BpmMetaConstants.BPM_TASK_NON_ADD_INSTANCE.equals(isAddInstance) || Objects.isNull(isAddInstance)) {

                    //todo 在这里完成更新上一个defKey?
                    execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, true);

                    //单人办毕加签
                } else if (BpmMetaConstants.BPM_TASK_IS_ADD_INSTANCE.equals(isAddInstance)) {

                    Boolean isCompleted = false;

                    Boolean addInstanceCompleted = false;
                    Boolean originCompleted = false;

                    //从redis里面获取
                    String addInstanceRedisKey = keyCacheMap.get(execution.getProcessInstanceId());

                    if (StringUtils.isEmpty(addInstanceRedisKey)) {
                        addInstanceRedisKey = BpmMetaConstants.BPM_COMPLETED_TYPE_GLOBAL
                                + BpmMetaConstants.REDIS_FILE_KEY_SEPTOR + execution.getProcessInstanceId();
                    }
                    Map<Object, Object> addInstanceMap = redisUtil.hmget(addInstanceRedisKey);
                    CompletedTypeDto addInstanceDto = new CompletedTypeDto();
                    BeanUtils.populate(addInstanceDto, addInstanceMap);

                    //判断任务完成类型
                    String completedType = addInstanceDto.getCompletedType();
                    //任务完成条件
                    String completedCondition = addInstanceDto.getCompletedCondition();
                    //当前人员办情况str
                    String curCompleted = addInstanceDto.getCurCompleted();

                    //加签人
                    String addInstancesStr = addInstanceDto.getAddInstancesStr();
                    //当前加签人办理情况
                    String curAddInstancesCompletedStr = addInstanceDto.getCurAddInstancesCompletedStr();

                    //原来的办理人
                    String originTaskOwnersStr = addInstanceDto.getOriginTaskOwnersStr();

                    //当前原办理人办理情况
                    String curOriginTaskOwnerCompletedStr = addInstanceDto.getCurOriginTaskOwnerCompletedStr();


                    log.info("#当前加签的场景: {},完成条件: {},未修改前的完成条件: {}#", completedType, completedCondition, curCompleted);
                    *//*
     *
     *    新办理规则： 原来办理人的一个人+ 所有的加签人
     *
     *
     *
     *
     *
     *//*
                    //本次回调任务办理人
                    String executionAssignee = execution.getAssignee();

                    //拼接当前办理人buider
                    StringBuffer appendAssigneBuffer = new StringBuffer(curCompleted);

                    //所有的加签办理人
                    List<String> allTaskAssigneList = new CopyOnWriteArrayList<>();
                    //所有的原任务办理人
                    List<String> orignTaskAssigneList = new CopyOnWriteArrayList<>();
                    //当前的加签任务办理人
                    List<String> curAddInstanceAssigneList = new Vector<>();
                    //当前原任务办理人
                    List<String> curOriginAssigneList = new Vector<>();

                    //在这里面
                    if (!addInstancesStr.contains(executionAssignee)) {

                        if (StringUtils.isEmpty(curOriginTaskOwnerCompletedStr)) {

                            curOriginTaskOwnerCompletedStr = new String(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR + executionAssignee);
                        } else {
                            curOriginTaskOwnerCompletedStr = curOriginTaskOwnerCompletedStr + BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR + executionAssignee;
                        }
                    } else {
                        //当前加签任务办理人
                        if (StringUtils.isEmpty(curAddInstancesCompletedStr)) {

                            curAddInstancesCompletedStr = new String(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR + executionAssignee);
                        } else {
                            curAddInstancesCompletedStr = curAddInstancesCompletedStr + BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR + executionAssignee;
                        }
                        List<String> asList = Arrays.asList(curAddInstancesCompletedStr);
                        curAddInstanceAssigneList = new CopyOnWriteArrayList(asList);

                        log.info("#需要办理人:{}#", completedCondition);
                        log.info("#当前办理人:{}#", curCompleted + BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR + executionAssignee);

                    }

                    if (StringUtils.isNonEmpty(curAddInstancesCompletedStr)) {
                        //处理完当前人，-- 进入到判断逻辑
                        List<String> tempAddInstanceList = Arrays.asList(addInstancesStr.split(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR));
                        allTaskAssigneList = new CopyOnWriteArrayList<>(tempAddInstanceList);
                        List<String> asList = Arrays.asList(curAddInstancesCompletedStr.split(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR));
                        curAddInstanceAssigneList = new CopyOnWriteArrayList(asList);

                        //移除""
                        if (Objects.nonNull(curAddInstanceAssigneList)) {
                            curAddInstanceAssigneList.remove("");
                        }
                        if (Objects.nonNull(allTaskAssigneList)) {
                            allTaskAssigneList.remove("");
                        }
                        //两个集合元素是否完全 -- 判断加签人
                        if (checkDiffrent(allTaskAssigneList, curAddInstanceAssigneList)) {
                            addInstanceCompleted = true;
                        }
                    }

                    //判断原任务人 -- 加入委托的场景
                    if (StringUtils.isNonEmpty(curOriginTaskOwnerCompletedStr)) {
                      *//*  //// TODO: 2022/7/7   为了保证再委托的场景下能够完成任务，需要进行从数据库里面捞真实数据
                        List<String> assigneList = actRuTaskMapper.selectCurTaskOwnerListForDelagate(processInstanceId);
                        StringBuilder assigneBuild = new StringBuilder();
                        assigneList.stream().forEach(cur -> {
                            assigneBuild.append(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR)
                                    .append(cur);
                        });*//*

                        //原任务人数
                        List<String> asListOrigin = Arrays.asList(originTaskOwnersStr.split(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR));
                        orignTaskAssigneList = new Vector<>(asListOrigin);
                        //移除加签人
                        final List<String> finalAllTaskAssigneList = allTaskAssigneList;
                        orignTaskAssigneList = orignTaskAssigneList.stream().filter(
                                b -> finalAllTaskAssigneList.stream().noneMatch(id -> Objects.equals(b, id))).collect(Collectors.toList());
                        //当前原原任务人办理情况
                        List<String> asListOriginCur = Arrays.asList(curOriginTaskOwnerCompletedStr.split(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR));
                        curOriginAssigneList = new Vector<>(asListOriginCur);


                        //移除""
                        if (Objects.nonNull(asListOrigin)) {
                            orignTaskAssigneList.remove("");
                        }
                        if (Objects.nonNull(asListOriginCur)) {
                            curOriginAssigneList.remove("");
                        }
                        for (String orign : orignTaskAssigneList) {

                            for (String cur : curOriginAssigneList) {

                                if (cur.equals(orign)) {
                                    originCompleted = true;
                                    break;
                                }
                            }
                        }

                    }

                    if (addInstanceCompleted && originCompleted) {

                        isCompleted = true;
                    }

                    if (isCompleted) {

                        //todo 在这里完成更新上一个defKey?
                        //完成任务
                        execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, true);
                    } else {
                        //更新到redis
                        //当前加签人办理情况
                        addInstanceMap.put(BpmMetaConstants.BPM_CUR_ADDINSTANCE_COMPELTED_TYPE_KEY, curAddInstancesCompletedStr);
                        //当前原办理人完成情况
                        addInstanceMap.put(BpmMetaConstants.BPM_CUR_ORIGIN__KEY, curOriginTaskOwnerCompletedStr);
                        redisUtil.hmset(addInstanceRedisKey, addInstanceMap);
                        execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, false);
                    }
                }

            } else if (completedTypeDto.getCompletedType().equals(BpmCompeleptedTypEnum.ALL_COMPLETED.getCode())) {

                //当前节点任务总数
                Integer nrOfInstances = (Integer) execution.getVariable(BpmMetaConstants.NR_OF_INSTANCES_KEY);
                //已经完成数目
                Integer nrOfCompletedInstances = (Integer) execution.getVariable(BpmMetaConstants.NR_OF_CONPLETED_INSTANCES_KEY);
                nrOfCompletedInstances++;

                if (nrOfCompletedInstances == nrOfInstances) {
                    execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, true);
                } else {
                    execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, false);
                }
            } else {

              *//*  StringBuffer addInstanceAssigneRedisKey = new StringBuffer(BpmMetaConstants.BPM_ADD_INSTANCE_ASSIGNE_KEY);
                addInstanceAssigneRedisKey.append(BpmMetaConstants.REDIS_LINE_KEY_SEPTOR)
                        .append(BpmMetaConstants.REDIS_LINE_KEY_SEPTOR).append(addInstanceDto.getProcessId())
                        .append(BpmMetaConstants.REDIS_LINE_KEY_SEPTOR).append(addInstanceDto.getTaskDefKey())
                        .append(BpmMetaConstants.REDIS_LINE_KEY_SEPTOR).append(addInstanceDto.getTaskId());


                log.info("#新构建的加签人key={}#", addInstanceAssigneRedisKey.toString());

                Map<Object, Object> addInstanceAssigneMap = redisUtil.hmget(addInstanceAssigneRedisKey.toString());

                AddInstanceCacheDto addInstanceCacheDto = new AddInstanceCacheDto();
                BeanUtils.populate(addInstanceCacheDto, addInstanceAssigneMap);


                //构建Key
                StringBuffer judeCompeletedKey = new StringBuffer();

                judeCompeletedKey.append(BpmCompeleptedTypEnum.ONE_COMPLETED.getCode().trim())
                        .append(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR)
                        .append(BpmMetaConstants.ADD_INSTANCE_ASSIGNE)
                        .append(BpmMetaConstants.REDIS_EQQUALS_KEY_SEPTOR)
                        .append(addInstanceCacheDto.getAssigne());

                log.info("#查找的KEY:{}#", addInstanceAssigneRedisKey.toString());
                //按照这个key查找
                if (redisUtil.hasKey(addInstanceAssigneRedisKey.toString())) {

                    //表名只有这个人加签-- 然后完成任务


                    execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, true);
                } else {
                    //更新到redis
                    addInstanceMap.put(BpmMetaConstants.BPM_COMPELTED_TTPE, judeCompeletedKey.toString());
                    redisUtil.hmset(addInstanceAssigneRedisKey.toString(), addInstanceMap);

                    execution.setVariable(BpmMetaConstants.BPM_COMPLETED_CONDITION_KEY, false);


                }
*//*

     *//* StringBuffer getKey = new StringBuffer(addInstanceAssigneRedisKey.toString());
                Set<String> keySet = redisTemplate.keys(getKey.append("*"));

                List<AddInstanceCacheDto> addInstanceCacheDtoList = new ArrayList<>();


                for (String key : keySet) {

                    Map<Object, Object> addInstanceAssigneMap = redisUtil.hmget(key);

                    AddInstanceCacheDto addInstanceCacheDto = new AddInstanceCacheDto();
                    BeanUtils.populate(addInstanceCacheDto, addInstanceAssigneMap);
                    addInstanceCacheDtoList.add(addInstanceCacheDto);

                }
               *//*


            }


        } else if (BpmMetaConstants.TASK_TYPE_DELTED.equals(eventName)) {


            String deleteProcessId = execution.getProcessInstanceId();
            String delteTaskDefKey = execution.getTaskDefinitionKey();
            String ruTaskId = execution.getId();

            curKeyBuider = new StringBuffer();
            curKeyBuider.append(BpmMetaConstants.BPM_COMPLETED_TYPE_GLOBAL).append(BpmMetaConstants.REDIS_FILE_KEY_SEPTOR)
                    .append(processInstanceId);


            *//*
     *  第一次完成任务的时候,判断redis中是否有ownerStr： 如果没有的话，就需要进设置ownler
     *
     *//*
            //从redis里面获取
            Map<Object, Object> addInstanceMap = redisUtil.hmget(curKeyBuider.toString());
            CompletedTypeDto completedTypeDto = new CompletedTypeDto();
            BeanUtils.populate(completedTypeDto, addInstanceMap);
            if (Objects.isNull(completedTypeDto.getOriginTaskOwnersStr())) {

                //从数据库里面查
                List<String> list = actRuTaskMapper.selectCurTaskOwnerList(processInstanceId);
                StringBuffer stringBuilder = new StringBuffer();

                list.stream().forEach(cur -> {
                    stringBuilder.append(BpmMetaConstants.REDIS_CONDITION_KEY_SEPTOR)
                            .append(cur);
                });
                log.info("#原来的任务拥有者{}#", stringBuilder.toString());

                addInstanceMap.put(BpmMetaConstants.BPM_CUR_CUR_TASK_OWNER_KEY, stringBuilder.toString());

                //将上一次的任务拥有者发步上去
                redisUtil.hmset(curKeyBuider.toString(), addInstanceMap);
            }


            *//*
     *   做数据的清理
     *      1:当前的任务去清除redis中缓存的加签人
     *      2:清除keyCacheMap的信息
     *
     *//*
            StringBuffer deleteInstanceAssigneRedisKey = new StringBuffer(BpmMetaConstants.BPM_ADD_INSTANCE_ASSIGNE_KEY);
            deleteInstanceAssigneRedisKey
                    .append(BpmMetaConstants.REDIS_LINE_KEY_SEPTOR).append(deleteProcessId)
                    .append(BpmMetaConstants.REDIS_LINE_KEY_SEPTOR).append(delteTaskDefKey)
                    .append(BpmMetaConstants.REDIS_LINE_KEY_SEPTOR).append(ruTaskId);

            log.info("#需要删除的key:{}#", deleteInstanceAssigneRedisKey.toString());
            redisUtil.del(deleteInstanceAssigneRedisKey.toString());

            //需要回表查询数据判断当前流程是否结束
            WorkFlowInstence workFlowInstence = workFlowInstenceMapper.selectByPrimaryKey(processInstanceId);

            if (!BpmMetaConstants.PROCESS_ACTIVE.equals(workFlowInstence.getState())) {
                //删除本地缓存。
                keyCacheMap.remove(curKeyBuider.toString());
                // 删除redis缓存
                redisUtil.del(curKeyBuider.toString());
            }

            //任务被删除后删除该任务的拥有者
            redisUtil.del(taskOwnerBuild.toString());
        }
    }


    public static Map<String, List<ActIdUser>> groupUsers(List<ActIdUser> waitList) {


        Map<String, List<ActIdUser>> map = new ConcurrentHashMap<>();

        for (ActIdUser actIdUser : waitList) {

            if (map.containsKey(actIdUser.getGroupName())) {

                List<ActIdUser> actIdUsers = map.get(actIdUser.getGroupName());
                actIdUsers.add(actIdUser);
            } else {
                List<ActIdUser> actIdUsers = new ArrayList<>();
                actIdUsers.add(actIdUser);
                map.put(actIdUser.getGroupName(), actIdUsers);
            }
        }

        return map;
    }

    private static boolean checkDiffrent(List<String> list, List<String> list1) {

        return list.stream().sorted().collect(Collectors.joining())
                .equals(list1.stream().sorted().collect(Collectors.joining()));
    }


    public static void main(String[] args) {

        List<String> waitTodealList = new ArrayList<>();

        List<ActRuTask> actRuTaskList = new ArrayList<>();

        waitTodealList.add("houhong");
        waitTodealList.add("houhong23");

        ActRuTask actRuTask = new ActRuTask();
        actRuTask.setId("houhong");
        actRuTaskList.add(actRuTask);
        ActRuTask actRuTask2 = new ActRuTask();
        actRuTask2.setId("houhong2");
        actRuTaskList.add(actRuTask2);


        //求差集
        List<String> exitKeyList = waitTodealList.stream().filter(
                b -> actRuTaskList.stream().map(ActRuTask::getId).noneMatch(origintaskId -> Objects.equals(b, origintaskId))).collect(Collectors.toList());

        System.out.println(exitKeyList);
    }
    public static void main(String[] args) {

        List<String> waitTodealList = new ArrayList<>();

        List<ActRuTask> actRuTaskList = new ArrayList<>();

        waitTodealList.add("houhong");
        waitTodealList.add("houhong23");

        ActRuTask actRuTask = new ActRuTask();
        actRuTask.setId("houhong");
        actRuTaskList.add(actRuTask);
        ActRuTask actRuTask2 = new ActRuTask();
        actRuTask2.setId("houhong2");
        actRuTaskList.add(actRuTask2);


        //求差集
        List<String> exitKeyList = waitTodealList.stream().filter(
                b -> actRuTaskList.stream().map(ActRuTask::getId).noneMatch(origintaskId -> Objects.equals(b, origintaskId))).collect(Collectors.toList());

        System.out.println(exitKeyList);
    }*/
}